package com.adtech.adms.device.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slstudio.acs.hms.device.DeviceInfo;
import org.slstudio.acs.hms.device.IDeviceManager;
import org.slstudio.acs.tr069.job.IDeviceJob;
import org.slstudio.acs.tr069.job.resulthandler.IJobResultHandler;

import com.adtech.adms.device.DeviceConstants;
import com.adtech.adms.device.pojo.GuiDevice;
import com.adtech.adms.device.pojo.GuiDevicenotify;
import com.adtech.adms.device.pojo.GuiPolicy;
import com.adtech.adms.device.service.DeviceService;
import com.adtech.adms.system.SystemConstants;
import com.adtech.adms.system.pojo.Topo;
import com.adtech.core.dao.HibernateDAO;
import com.adtech.core.dao.exp.Expression;
import com.adtech.core.dao.query.Pager;
import com.adtech.core.dao.query.QueryConstants;
import com.adtech.core.dao.query.QueryCriterions;
import com.adtech.core.dao.query.Sort;
import com.adtech.core.exception.ServiceException;

public class DeviceServiceImpl implements DeviceService,IDeviceManager,IJobResultHandler{
	private HibernateDAO dao;
	@Override
	public List<GuiDevice> getDeviceList(Pager pager, Expression expression,
			Sort sort, List<Topo> topos) {
		if(sort==null || sort.isEmpty()) {
			sort = new Sort();
			sort.addSort(DeviceConstants.Device.ID, QueryConstants.DESC);
		}
		List<GuiDevice> devices = (List<GuiDevice>)dao.getByQuery(GuiDevice.class, pager, expression, sort);
		devices = filterDeviceByTopo(devices, topos);
		return devices;
	}

	private List<GuiDevice> filterDeviceByTopo(List<GuiDevice> devices, List<Topo> topos) {
		if(topos == null || topos.isEmpty()){
			return null;
		}
		List<GuiDevice> tmpDevices = new ArrayList<GuiDevice>();
		for(GuiDevice device :devices){
			if(isDeviceContainedInTopos(device, topos)){
				tmpDevices.add(device);
			}
		}
		// TODO Auto-generated method stub
		return tmpDevices;
	}

	private boolean isDeviceContainedInTopos(GuiDevice device, List<Topo> topos) {
//		Topo existTopo = (Topo) dao.loadById(Topo.class,device.getTopoSid());
		for(Topo topo : topos){
			if(topo!=null &&topo.getNodeid()!= null && topo.getNodeid().equalsIgnoreCase(device.getTopoSid().toString())){
				device.setFullPath(topo.getFullPath());
				return true;
			}
		}
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public void add(GuiDevice device) throws ServiceException {
			//ALTER TABLE `gui_device` ADD UNIQUE INDEX `imsi` (`imsi`);
			Set tempSet = new HashSet();
			tempSet.add("");
			device.setStatus(DeviceConstants.Device.DEVICE_STATUS_OPEND);
			device.setCanceled(false);
			device.setProtocol("");
			device.setDevOrderStatus(new Integer(1));
			device.setDevAlarmNames("");
			device.setParameterKey("");
			device.setProvisioningCode("");
			device.setVdtId(1);
			device.setPlatform("");
			device.setRunOs("");
			device.setResolution("");
			device.setGuiDeviceactions(tempSet);
			device.setGuiDevicenotify(new GuiDevicenotify());
			device.setGuiDevicehistoryactions(tempSet);
			device.setGuiDevicedatamodels(tempSet);
			dao.add(device);
			return;
	}
	@Override
	public void save(GuiDevice device) throws ServiceException {
		
//		Topo existTopo = (Topo) dao.loadById(Topo.class,device.getTopoSid());
//		if(existTopo == null){
//			return;
//		}
//		device.setTopoSid(new Long(existTopo.getNodeid()));
		
		if (device.getId() == null) {
			Set tempSet = new HashSet();
			tempSet.add("");
			device.setStatus(DeviceConstants.Device.DEVICE_STATUS_OPEND);
			device.setCanceled(false);
			device.setProtocol("");
			device.setDevOrderStatus(new Integer(1));
			device.setDevAlarmNames("");
			device.setParameterKey("");
			device.setProvisioningCode("");
			device.setVdtId(1);
			device.setPlatform("");
			device.setRunOs("");
			device.setResolution("");
			device.setGuiDeviceactions(tempSet);
			device.setGuiDevicenotify(new GuiDevicenotify());
			device.setGuiDevicehistoryactions(tempSet);
			device.setGuiDevicedatamodels(tempSet);
			dao.add(device);
			return;
		}
		
		
		GuiDevice existDevice = (GuiDevice) dao.loadById(GuiDevice.class,
				device.getId());
		
		mergeDevice(existDevice, device);
		dao.saveOrUpdate(existDevice);
		
		
	}
	
	private void mergeDevice(GuiDevice existDevice, GuiDevice device) {
		existDevice.setImsi(device.getImsi());
		existDevice.setMdn(device.getMdn());
		existDevice.setTopoSid(device.getTopoSid());
		existDevice.setDevManufac(device.getDevManufac());
		existDevice.setSubscriberAddress(device.getSubscriberAddress());
		
		existDevice.setTopoSid(device.getTopoSid());
		
	}

	public void setDao(HibernateDAO dao) {
		this.dao = dao;
	}
	
	public void delete(String id) {
		if (id == null || id.length() == 0) {
			return;
		}
		String[] ids = id.split(",");
		for(String deviceId : ids) {
			if(deviceId!=null && deviceId.length()>0) {
				GuiDevice device = dao.getById(GuiDevice.class, Integer.parseInt(deviceId));
				dao.delete(device);
			}
		}
		dao.flushSession();
	}

	@Override
	public void addDevice(String deviceKey, DeviceInfo device) {
		
	}

	@Override
	public void clearDevices() {
		
	}

	@Override
	public DeviceInfo findDevice(String deviceKey) {
		QueryCriterions hc = new QueryCriterions();
		hc.and(SystemConstants.Device.KEY, deviceKey, QueryConstants.EQ);
		GuiDevice device = dao.getOneByQuery(GuiDevice.class, hc.toExpression());
		if(device==null)
			return null;
	
		DeviceInfo info=new DeviceInfo();
		info.setDeviceID(device.getId().toString());
		info.setDeviceKey(device.getImsi());
		info.setManufacturer(device.getDevManufac());
        info.setDeviceOUI(device.getDevOui());
        info.setProductClass(device.getPclass());
        info.setSerialNumber(device.getDevSn());
        info.setCrURL("http://192.168.0.100:9892/acscall");
        info.setCrUsername(device.getAcsUser());
        info.setCrPassword(device.getAcsPass());
        info.setLastInformTime(new Date());
		return info;
	}

	@Override
	public List<DeviceInfo> getAllDeviceList() {
		return null;
	}

	@Override
	public void removeDevice(String deviceKey) {
		
	}

	@Override
	public void onFailed(IDeviceJob job) {
		QueryCriterions hc = new QueryCriterions();
		hc.and(SystemConstants.Device.KEY, job.getDeviceKey(), QueryConstants.EQ);
		GuiDevice device = dao.getOneByQuery(GuiDevice.class, hc.toExpression());
		device.setStatus(DeviceConstants.Device.DEVICE_STATUS_INACTIVATED);
		device.setProvisioningCode(String.valueOf(job.getErrorCode()));
		dao.saveOrUpdate(device);
	}

	@Override
	public void onSucceed(IDeviceJob job) {
		QueryCriterions hc = new QueryCriterions();
		hc.and(SystemConstants.Device.KEY, job.getDeviceKey(), QueryConstants.EQ);
		GuiDevice device = dao.getOneByQuery(GuiDevice.class, hc.toExpression());
		device.setStatus(DeviceConstants.Device.DEVICE_STATUS_ACTIVATED);
		device.setProvisioningCode(String.valueOf(job.getErrorCode()));
		dao.saveOrUpdate(device);
	}

	@Override
	public GuiDevice getDevice(String deviceKey) {
		QueryCriterions hc = new QueryCriterions();
		hc.and(SystemConstants.Device.KEY, deviceKey, QueryConstants.EQ);
		GuiDevice device = dao.getOneByQuery(GuiDevice.class, hc.toExpression());
		if(device==null)
			return null;
	
		return device;
	}

	

}
